/**
 * https://www.mm.chenchen
 * <p>
 * 版权所有，侵权必究！
 */

package mm.chenchen.log.aspect;


import lombok.extern.slf4j.Slf4j;
import mm.chenchen.log.annotation.YcLog;
import mm.chenchen.log.constant.YcLogLevel;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 多数据源，切面处理类
 */
@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@Slf4j
public class YcLogAspect {
    //protected Logger logger = LoggerFactory.getLogger(getClass());

    @Pointcut("@annotation(mm.chenchen.log.annotation.YcLog) " +
            "|| @within(mm.chenchen.log.annotation.YcLog)")
    public void ycLogPointCut() {

    }

    @Around("ycLogPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Class targetClass = point.getTarget().getClass();
        Method method = signature.getMethod();

        YcLog targetDataSource = (YcLog) targetClass.getAnnotation(YcLog.class);
        YcLog methodDataSource = method.getAnnotation(YcLog.class);
        YcLogLevel level = YcLogLevel.DEBUG;

        if (targetDataSource != null || methodDataSource != null) {
            //方法注解优先类
            if (methodDataSource != null) {
                level = methodDataSource.level();
            } else {
                level = targetDataSource.level();
            }
            switch (level) {
                case DEBUG:
                    log.debug("【" + targetClass + " : " + point.getSignature().getName() + "】方法执行,参数是：" + Arrays.asList(point.getArgs()));
                    break;
                case INFO:
                    log.info("【" + targetClass + " : " + point.getSignature().getName() + "】方法执行,参数是：" + Arrays.asList(point.getArgs()));
                    break;
                case WARN:
                    log.warn("【" + targetClass + " : " + point.getSignature().getName() + "】方法执行,参数是：" + Arrays.asList(point.getArgs()));
                    break;
                case ERROR:
                    log.error("【" + targetClass + " : " + point.getSignature().getName() + "】方法执行,参数是：" + Arrays.asList(point.getArgs()));
                    break;
            }
        }
        Object ob = new Object();
        try {
            ob = point.proceed();
            return ob;
        } finally {
            switch (level) {
                case DEBUG:
                    log.debug("【" + targetClass + " : " + point.getSignature().getName() + "】方法执行完毕,返回结果是：" + ob);
                    break;
                case INFO:
                    log.info("【" + targetClass + " : " + point.getSignature().getName() + "】方法执行完毕,返回结果是：" + ob);
                    break;
                case WARN:
                    log.warn("【" + targetClass + " : " + point.getSignature().getName() + "】方法执行完毕,返回结果是：" + ob);
                    break;
                case ERROR:
                    log.error("【" + targetClass + " : " + point.getSignature().getName() + "】方法执行完毕,返回结果是：" + ob);
                    break;
            }
        }
    }
}